//
//  DCOSSDDownloadOpration.m
//  DCDownloadOpration
//
//  Created by collegepre on 16/7/26.
//  Copyright © 2016年 Wade. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "DCOSSDDownloadOpration.h"

#import "DCDownload.h"
#import "NSString+DCDownload.h"
#import "DCDownloadOprationManager.h"

static NSString *const OSSALiyunKEY = @"eW5YMurlGXH8Kswa";

static NSString *const OSSALiyunKEYSecret = @"58NOhmAiho6mHq1dILf3j2nt9kuOp2";

static NSString *const OSSALiyunBucket = @"class-server";
static NSString *const OSSALiyunEndpoint = @"https://oss-cn-beijing.aliyuncs.com";


static NSString *const OSSALiyunUploadScreenshotURL = @"https://oss-cn-beijing.aliyuncs.com";
static NSString *const OSSALiyunDownloadScreenshotURL = @"https://app-data.oss-cn-beijing.aliyuncs.com";

#define DCCachesPath  [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]

@interface DCOSSDDownloadOpration()<UIAlertViewDelegate>



@property (nonatomic, strong) NSOperationQueue *downloadOprationQueue;

@property (nonatomic, strong)  NSOperationQueue *uploadOprationQueue;

@property (nonatomic, strong) OSSClient *downloadOSSClient;
@property (nonatomic, strong) OSSTask * downloadTask;

@property (nonatomic, strong) NSMutableArray *downloadingOpration;
@property (nonatomic, strong) NSMutableArray *waitDownloadOpration;

@end

@implementation DCOSSDDownloadOpration

// 正在下载的进程
- (NSMutableArray *)downloadingOpration{
    if (!_downloadingOpration) {
        _downloadingOpration = [NSMutableArray array];
    }
    return _downloadingOpration;
}


// 等待下载的进程
- (NSMutableArray *)waitDownloadOpration{
    if(!_waitDownloadOpration){
        _waitDownloadOpration = [NSMutableArray array];
    }
    return _waitDownloadOpration;
}

/****************************单利模式**********************************************/
//static  id _instace = nil;
//
//+ (instancetype)allocWithZone:(struct _NSZone *)zone{
//    if (_instace == nil) {
//        static dispatch_once_t onceToken;
//        dispatch_once(&onceToken, ^{
//            _instace = [super allocWithZone:zone];
//        });
//    }
//    
//    return _instace;
//}
//
//- (instancetype)init{
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        _instace = [super init];
//        
//    });
//    return _instace;
//}
//
//- (id)copy{
//    return _instace;
//}
//
//- (id)mutableCopy{
//    return _instace;
//}
//
+ (instancetype)shareOSSDownloadOpration{
    return [[self alloc] init];
}

/**************************************************************************/

- (NSOperationQueue *)downloadOprationQueue{
    if (!_downloadOprationQueue) {
        _downloadOprationQueue = [[NSOperationQueue alloc] init];
    }
    return _downloadOprationQueue;
}

- (OSSClient *)downloadOSSClient{
    if (!_downloadOSSClient) {
        NSString *endpoint =OSSALiyunEndpoint;
        
        id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:OSSALiyunKEY secretKey:OSSALiyunKEYSecret];
        
        _downloadOSSClient = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential];
        OSSClientConfiguration *config= [[OSSClientConfiguration alloc] init];
        config.maxRetryCount = 1;
        config.maxConcurrentRequestCount = 2;
        [_downloadOSSClient setClientConfiguration:config];
    }
    return _downloadOSSClient;
}

/**
 *  类下载方法
 *
 *  @param info       下载信息
 *  @param progress   进度回调Block
 *  @param complition 完成回调Block
 *
 *  @return 下载进程
 */
- (void)CPOSSDownloadWithDownloadInfo:(CPDownloadInfo *)info downloadProgress:(CPDownloadProgress)progress complition:(CPDonwloadCompliction)complition {
    
    __block typeof(self) wsSelf = self;
//    if (self.downloadingOpration.count < 3) {
        NSBlockOperation *blockOpration = [NSBlockOperation blockOperationWithBlock:^{
            if (info.osskey.isNotEmpty) { // 通过OSSKey下载
                // 下载方法
                [wsSelf CPOSSPartDownloadWithWithDownloadInfo:info downloadProgress:progress complition:complition];
                
            }else{ // 通过URL地址下载
                [wsSelf CPOSSDownloadByURLStringWithDownloadInfo:info downloadProgress:progress complition:complition];
            }
        }];
        
    [self.downloadOprationQueue addOperation:blockOpration];
}

/**
 *  通过URL地址下载课件包
 *
 *  @param info       下载信息
 *  @param progress   进度回调
 *  @param complition 完成回到哦
 */
- (void)CPOSSDownloadByURLStringWithDownloadInfo:(CPDownloadInfo *)info downloadProgress:(CPDownloadProgress)progress complition:(CPDonwloadCompliction)complition
{
    __weak typeof(self) weakSelf = self;
    self.progressBlock = progress;
    self.donloadCompliction = complition;
    DCDownloadOprationManager *manager = [DCDownloadOprationManager managerWithIdentifier:@"coursePakageDownload"];
    [manager download:info.downloadURL toDestinationPath:info.destinationPath progress:^(NSInteger curentBytes, NSInteger TotalBytes, DCDownloadOpration *downloadopration) {
        weakSelf.progressBlock(curentBytes,TotalBytes,curentBytes / (float)TotalBytes);
        if (curentBytes == TotalBytes) { // 下载成功
            weakSelf.donloadCompliction(nil);
        }
    } state:^(DCDownloadState state, NSString *file, NSError *error, DCDownloadOpration *downloadopration) {
        if (state == DCDownloadStateCompleted  && error) { // 下载失败
            weakSelf.donloadCompliction(error);
        }
    }];

}

- (void)CPOSSPartDownloadWithWithDownloadInfo:(CPDownloadInfo *)info downloadProgress:(CPDownloadProgress)progress complition:(CPDonwloadCompliction)complition
{
    _isSpuased = YES;

    self.osskey = info.osskey;
    self.progressBlock = progress;
    self.donloadCompliction = complition;
    
    OSSHeadObjectRequest * head = [OSSHeadObjectRequest new];
    
    head.bucketName = OSSALiyunBucket;
    head.objectKey = info.osskey;

    self.downloadTask = [self.downloadOSSClient headObject:head];
    __block typeof(self) weakSelf = self;
    // 请求文件在服务器信息
    [self.downloadTask continueWithBlock:^id(OSSTask *task) {
        if (!task.error) {
            // 获取OSS服务器上的文件下载长度
            OSSHeadObjectResult * headResult = task.result;
             NSNumber *totalSize = headResult.objectMeta[@"Content-Length"];
            weakSelf.totleLength = totalSize.integerValue;
            NSFileManager *mgr = [NSFileManager defaultManager];
            NSString *zipPath = info.destinationPath;
            
            NSDictionary *dict = [mgr attributesOfItemAtPath:zipPath error:nil];
            if (dict) {
                NSNumber *filesize = dict[@"NSFileSize"];
                
              if (totalSize.integerValue > filesize.integerValue) {
                    // 下载
                    [weakSelf OSSDownloadWithWithDownloadInfo:info currentLength:filesize.integerValue totalLength:totalSize.integerValue downloadProgress:^(NSInteger currentLength, NSInteger totalLength, float pro) {
                        weakSelf.progressBlock(currentLength,totalLength,pro);
                    } complition:^(NSError *error) {
                        weakSelf.donloadCompliction(error);
                    }];
                }else if(totalSize.integerValue < filesize.integerValue){
                    // 删除路径再下载
                    
                   BOOL isSuccess = [mgr removeItemAtPath:zipPath error:nil];
                    if (isSuccess) {
                        [mgr createFileAtPath:zipPath contents:nil attributes:nil];
                        // 下载
                        [weakSelf OSSDownloadWithWithDownloadInfo:info currentLength:0 totalLength:totalSize.integerValue downloadProgress:^(NSInteger currentLength, NSInteger totalLength, float pro) {
                            weakSelf.progressBlock(currentLength,totalLength,pro);
                        } complition:^(NSError *error) {
                            weakSelf.donloadCompliction(error);
                        }];
                    }
                }else{ // 相等不用下载
                    progress(totalSize.integerValue,totalSize.integerValue,1.0);
                    complition(nil);
                }
            }else{ // 文件不存在
                BOOL isSuc = [mgr createFileAtPath:zipPath contents:[NSData data] attributes:nil];
                if (isSuc) {
                    [weakSelf OSSDownloadWithWithDownloadInfo:info currentLength:0 totalLength:totalSize.integerValue downloadProgress:^(NSInteger currentLength, NSInteger totalLength, float pro) {
                        weakSelf.progressBlock(currentLength,totalLength,pro);
                    } complition:^(NSError *error) {
                        weakSelf.donloadCompliction(error);
                    }];
                }else{
                    progress(0,0,-1.0f);
                    NSError *error = [NSError errorWithDomain:@"初始创建Zip文件失败" code:1002 userInfo:@{@"destinationPath":info.destinationPath,@"ossid":info.osskey}];
                    complition(error);
                }
            }
        } else {
            progress(0,0,0);
             complition(task.error);
            if(task.error.code == 403){
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Download failed!" message:@"Need your iPad set date audomatically,if you want to reset,click 'YES' button." delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"YES", nil];
                [alert show];
            }
        }
        return nil;
    }];
}



/**
 *  内部对象方法
 *
 *  @param info          下载信息
 *  @param currentLength 当前文件长度
 *  @param totalLength   总长度
 *  @param progress      进度回调
 *  @param compliton     完成回调
 */
- (void)OSSDownloadWithWithDownloadInfo:(CPDownloadInfo *)info currentLength:(NSInteger)currentLength totalLength:(NSInteger)totalLength downloadProgress:(CPDownloadProgress)progress complition:(CPDonwloadCompliction)compliton
{
    _isSpuased = NO;
    
    OSSGetObjectRequest * request = [OSSGetObjectRequest new];
    request.bucketName = OSSALiyunBucket;
    request.objectKey = info.osskey;
    request.range = [[OSSRange alloc] initWithStart:currentLength withEnd:totalLength - 1]; // bytes=1-99
    request.downloadProgress = ^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
        //        NSLog(@"%lld, %lld, %lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
        float percentage = (float)(totalBytesWritten + currentLength)  / (totalBytesExpectedToWrite + currentLength);
        
        progress(totalBytesWritten + currentLength,totalBytesExpectedToWrite + currentLength,percentage);
    };
    
    NSString *zipPath = info.destinationPath;
    NSFileHandle *writeHandle = [NSFileHandle fileHandleForWritingAtPath:zipPath];
    
    request.onRecieveData = ^(NSData *data){
        [writeHandle seekToEndOfFile];
        [writeHandle writeData:data];
    };
    
    self.downloadTask = [self.downloadOSSClient getObject:request];
    
    [self.downloadTask continueWithBlock:^id(OSSTask *task) {
        
        [writeHandle closeFile];
        
        compliton(task.error);
        if (task.error) {
            NSLog(@"download object failed, error: %@" ,task.error);
        }
        return nil;
    }];
}


/**
 *  OSS服务器的下载方法
 *
 *  @param objectKey  Key值
 *  @param filePath   文件下载路径
 *  @param progress   进度回调
 *  @param complition 完成回调
 */
- (void)OSSDownloadWithOSSobjectKey:(NSString *)objectKey detectPath:(NSString *)filePath downloadProgress:(CPDownloadProgress)progress complition:(CPDonwloadCompliction)complition
{
    NSFileManager *mgr = [NSFileManager defaultManager];
    if (![mgr fileExistsAtPath:filePath]) {
        [mgr createFileAtPath:filePath contents:nil attributes:nil];
    }
    
    OSSGetObjectRequest * request = [OSSGetObjectRequest new];
    request.bucketName = OSSALiyunBucket;
    request.objectKey = objectKey;

    request.downloadProgress = ^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
        float percentage = (float)(totalBytesWritten)  / (totalBytesExpectedToWrite);
        progress(totalBytesWritten ,totalBytesExpectedToWrite ,percentage);
        
    };
    
    NSFileHandle *writeHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
    
    request.onRecieveData = ^(NSData *data){
        [writeHandle seekToEndOfFile];
        [writeHandle writeData:data];
    };
    // Aliyun授权
    NSString *endpoint = @"oss-cn-beijing.aliyuncs.com";
    
    id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:OSSALiyunKEY secretKey:OSSALiyunKEYSecret];
    
    OSSClient *client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential];
    
    OSSTask * getTask = [client getObject:request];
    
    [getTask continueWithBlock:^id(OSSTask *task) {
        [writeHandle closeFile];
        if (!task.error) {
            NSLog(@"download object success!");
        } else {
            NSLog(@"download object failed, error: %@" ,task.error);
        }
        return nil;
    }];
}

// 通过URL下载的方法

/**
 *  OSS服务器文件上传方法<因暂时无大文件上传,暂不提供断点上传功能>
 *
 *  @param filePath 文件路径
 *  @param fileName 上传的文件名
 *  @param sucess   成功回调
 *  @param fail     失败回调
 */
- (void)upLoadFiletoAliyunServerWithPngName:(NSString *)filePath uploadFileName:(NSString *)fileName uploadSucess:(void (^)(NSString *))sucess fail:(void (^)())fail{

}


- (void)sendtoAliyunServerWithPngName:(NSString *)filePath uploadFileName:(NSString *)fileName uploadSucess:(void (^)(NSString *))sucess fail:(void (^)())fail{
    
    NSBlockOperation *blockOpration = [NSBlockOperation blockOperationWithBlock:^{
        NSString *pngName = [[filePath lastPathComponent] stringByDeletingPathExtension];
        // Aliyun授权
        NSString *endpoint = [NSString stringWithFormat:@"%@/%@",OSSALiyunUploadScreenshotURL,@"whiteboardscreenshot"];
        id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:OSSALiyunKEY secretKey:OSSALiyunKEYSecret];
        
        OSSClient *client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential];
        
        OSSPutObjectRequest * put = [OSSPutObjectRequest new];
        
        // 必填字段
        put.bucketName = OSSALiyunBucket;
        put.objectKey = fileName;
        
        put.uploadingFileURL = [NSURL fileURLWithPath:filePath];
        
        put.contentType = @"image/png";
        put.contentDisposition = pngName;
        
        OSSTask * putTask = [client putObject:put];
        
        [putTask continueWithBlock:^id(OSSTask *task) {
            if (!task.error) {
                NSString *imageURL = [OSSALiyunDownloadScreenshotURL stringByAppendingPathComponent:fileName];
                
                [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
                if(sucess){
                    sucess(imageURL);
                }
            } else {
                if(fail){
                    fail();
                }
            }
            return nil;
        }];
    }];
    
    [self.downloadOprationQueue addOperation:blockOpration];
}
@end
